package com.carAnalysisAdmin.system.controller;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.carAnalysisAdmin.common.core.domain.model.LoginUser;
import com.carAnalysisAdmin.common.utils.DateUtils;
import com.carAnalysisAdmin.common.utils.ElevatorystemUtil;
import com.carAnalysisAdmin.system.domain.SysParkSpot;
import com.carAnalysisAdmin.system.domain.UserGoTime;
import com.carAnalysisAdmin.system.domain.UserSpotInfo;
import com.carAnalysisAdmin.system.mapper.UserSpotInfoMapper;
import com.carAnalysisAdmin.system.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.carAnalysisAdmin.common.annotation.Log;
import com.carAnalysisAdmin.common.core.controller.BaseController;
import com.carAnalysisAdmin.common.core.domain.AjaxResult;
import com.carAnalysisAdmin.common.enums.BusinessType;
import com.carAnalysisAdmin.system.domain.SysParkFloor;
import com.carAnalysisAdmin.common.utils.poi.ExcelUtil;
import com.carAnalysisAdmin.common.core.page.TableDataInfo;

/**
 * 楼层管理Controller
 * 
 * @author ruoyi
 * @date 2024-04-14
 */
@RestController
@RequestMapping("/system/floor")
public class SysParkFloorController extends BaseController {
    @Autowired
    private ISysParkFloorService sysParkFloorService;
    @Autowired
    private ISysParkSpotService sysParkSpotService;
    @Autowired
    private UserSpotInfoMapper userSpotInfoMapper;

    @Autowired
    private IUserGoTimeService userGoTimeService;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private IUserSpotInfoService userSpotInfoService;
    /**
     * 查询楼层管理列表
     */
    @GetMapping("/list")
    public TableDataInfo list(SysParkFloor sysParkFloor) {
        startPage();
        List<SysParkFloor> list = sysParkFloorService.selectSysParkFloorList(sysParkFloor);
        return getDataTable(list);
    }
    @GetMapping("/all")
    public TableDataInfo all(SysParkFloor sysParkFloor) {
        List<SysParkFloor> list = sysParkFloorService.selectSysParkFloorList(sysParkFloor);
        return getDataTable(list);
    }

    /**
     * 导出楼层管理列表
     */
    @Log(title = "楼层管理", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, SysParkFloor sysParkFloor)
    {
        List<SysParkFloor> list = sysParkFloorService.selectSysParkFloorList(sysParkFloor);
        ExcelUtil<SysParkFloor> util = new ExcelUtil<SysParkFloor>(SysParkFloor.class);
        util.exportExcel(response, list, "楼层管理数据");
    }

    /**
     * 获取楼层管理详细信息
     */
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        SysParkFloor sysParkFloor = sysParkFloorService.selectSysParkFloorById(id);
        if (sysParkFloor != null){
            List<SysParkSpot> list = sysParkSpotService.selectSysParkSpotByFloor(sysParkFloor.getId());
            list.forEach(item ->{
                UserSpotInfo userSpotInfo = userSpotInfoMapper.selectUserSpotInfoByCode(item.getCode());
                if (userSpotInfo != null){
                    item.setUserName(userSpotInfo.getUserName());
                    item.setUserAvatar(userSpotInfo.getUserAvatar());
                    item.setUserId(userSpotInfo.getUserId());
                    item.setIsHaveUser("1");
                }else {
                    item.setIsHaveUser("0");
                }
            });
            sysParkFloor.setSysParkSpotList(list);
        }
        return success(sysParkFloor);
    }

    /**
     * 新增楼层管理
     */
    @Log(title = "楼层管理", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody SysParkFloor sysParkFloor, @RequestBody String spot) {
        JSONObject param = JSON.parseObject(spot);
        Integer spots;
        if (param != null && !param.isEmpty()){
            spots = Integer.parseInt(param.getString("spot"));
        }else {
            return AjaxResult.error();
        }
        return toAjax(sysParkFloorService.insertSysParkFloor(sysParkFloor, spots));
    }

    /**
     * 修改楼层管理
     */
    @Log(title = "楼层管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody SysParkFloor sysParkFloor)
    {
        return toAjax(sysParkFloorService.updateSysParkFloor(sysParkFloor));
    }

    /**
     * 删除楼层管理
     */
    @Log(title = "楼层管理", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(sysParkFloorService.deleteSysParkFloorByIds(ids));
    }

    @GetMapping("/savePayMoney/{goFloorId}/{time}/{money}")
    public AjaxResult savePayMoney(@PathVariable Long goFloorId, @PathVariable Long time, @PathVariable Long money) {
        // 获取用户所停车位、楼层
        UserSpotInfo userSpotInfo = userSpotInfoMapper.selectUserSpotInfoByUserId(getUserId());
        SysParkSpot sysParkSpot = sysParkSpotService.selectSysParkSpotByCode(userSpotInfo.getSpotCode());
        // 用户车当前所在楼层
        Integer floorId = sysParkSpot.getFloorId();
        // 将用户所在楼层和所要去的楼层插入表中，在一个时间段内
        UserGoTime userGoTime = new UserGoTime();
        userGoTime.setGoFloor(goFloorId);
        userGoTime.setBeginTime(new Date());
        userGoTime.setUserId(getUserId());
        userGoTime.setOldFloor(floorId.longValue());
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MINUTE, time.intValue());
        userGoTime.setEndTime(calendar.getTime());
        userGoTimeService.insertUserGoTime(userGoTime);
        userSpotInfo.setAmountConsumption(String.valueOf(money));
        userSpotInfo.setQutboundTime(calendar.getTime());
        userSpotInfoService.updateUserSpotInfo(userSpotInfo);
        // 更新用户余额
        LoginUser loginUser = getLoginUser();
        if (loginUser.getUser().getMoney() <= 0 || loginUser.getUser().getMoney() < money){
            return AjaxResult.error("余额不足");
        }
        loginUser.getUser().setMoney(loginUser.getUser().getMoney() - money);
        sysUserService.updateUser(loginUser.getUser());
//        userGoTime.setEndTime();
        return success(true);
    }

    /*
    * 计算出库前需要缴费金额
    * */
    @GetMapping("/getPayMoney/{goFloorId}")
    public AjaxResult getPayMoney(@PathVariable Long goFloorId) {
        JSONObject result = new JSONObject();
        // 获取用户所停车位、楼层
        UserSpotInfo userSpotInfo = userSpotInfoMapper.selectUserSpotInfoByUserId(getUserId());
        SysParkFloor sysParkFloor = new SysParkFloor();
        // 查询楼层总数
        List<SysParkFloor> sysParkFloors = sysParkFloorService.selectSysParkFloorList(sysParkFloor);
        // 根据车位code获取楼层信息
        if (userSpotInfo != null){
            SysParkSpot sysParkSpot = sysParkSpotService.selectSysParkSpotByCode(userSpotInfo.getSpotCode());
            // 用户车当前所在楼层
            Integer floorId = sysParkSpot.getFloorId();
            Date beginTime = userSpotInfo.getWarehousingTime();
            // 讲用户所在楼层和所要去的楼层进行比较
            if (floorId.equals(goFloorId)){
                // 表明用户不需要转楼层，直接计算停车时长价格
                BigDecimal price = sysParkSpot.getPrice().multiply(BigDecimal.valueOf(DateUtils.timeDistanceHour(new Date(), beginTime)));
                result.put("maxTime", 0);
                result.put("price", price);
                return success(result);
            }else {
                // 先查询是否在当前时间段内有排队的车辆
                List<UserGoTime> list = userGoTimeService.selectUserGoTimeListByTime();
                if (list.size() > 0 ){
                    int[] sourceFloors = new int[list.size()];
                    int[] destinationFloors = new int[list.size()];
                    for (int i = 0; i < list.size(); i++) {
                        Stream<SysParkFloor> sysParkFloorStream = sysParkFloors.stream().filter(item -> item.getId() == goFloorId);
                        Stream<SysParkFloor> sysParkFloorStreamOld = sysParkFloors.stream().filter(item -> item.getId() == floorId.longValue());
                        List<SysParkFloor> collect = sysParkFloorStream.collect(Collectors.toList());
                        List<SysParkFloor> collectOld = sysParkFloorStreamOld.collect(Collectors.toList());
                        List<SysParkFloor> collectOne = sysParkFloors.stream().filter(item -> item.getId() == list.get(i).getOldFloor().intValue()).collect(Collectors.toList());
                        List<SysParkFloor> collectOldOne = sysParkFloors.stream().filter(item -> item.getId() == list.get(i).getGoFloor().intValue()).collect(Collectors.toList());
                        sourceFloors[i] = collectOne.get(0).getSort();
                        destinationFloors[i] = collectOldOne.get(0).getSort();
                        int numFloors = sysParkFloors.size();
                        int maxTime = ElevatorystemUtil.getMaxTime(sourceFloors, destinationFloors, numFloors);
                        BigDecimal price = sysParkSpot.getPrice().multiply(BigDecimal.valueOf(DateUtils.timeDistanceHour(new Date(), beginTime))).add(BigDecimal.valueOf((collect.get(0).getSort() - collectOld.get(0).getSort() < 0 ? -(collect.get(0).getSort() - collectOld.get(0).getSort()) : collect.get(0).getSort() - collectOld.get(0).getSort()) * 2));
                        result.put("maxTime", maxTime);
                        result.put("price", price);
                        return success(result);
                    }
                }else {
                    Stream<SysParkFloor> sysParkFloorStream = sysParkFloors.stream().filter(item -> item.getId()==goFloorId);
                    Stream<SysParkFloor> sysParkFloorStreamOld = sysParkFloors.stream().filter(item -> item.getId()==floorId.longValue());
                    List<SysParkFloor> collect = sysParkFloorStream.collect(Collectors.toList());
                    List<SysParkFloor> collectOld = sysParkFloorStreamOld.collect(Collectors.toList());
                    int[] sourceFloors = {collect.get(0).getSort()};
                    int[] destinationFloors = {collectOld.get(0).getSort()};
                    int numFloors = sysParkFloors.size();
                    // 计算需要多久时间
                    int maxTime = ElevatorystemUtil.getMaxTime(sourceFloors, destinationFloors, numFloors);
                    // 计算预计价格
                    // 计算当前时间与入库时间的时间差的价格
                    BigDecimal price = sysParkSpot.getPrice().multiply(BigDecimal.valueOf(DateUtils.timeDistanceHour(new Date(), beginTime)));
                    result.put("maxTime", maxTime);
                    result.put("price", price);
                    return success(result);
                }


            }
        }
        return success();
    }
}
